#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <unistd.h>

using namespace std;

// 函数声明
void grep(const string& pattern, istream& input, bool ignoreCase, bool highlight);
void usage(int status);

int main(int argc, char* argv[]) {
    if(argc == 2 && std::string(argv[1]) == "--help") {
    	usage(EXIT_SUCCESS); // 判断是否输出帮助信息
    	return 0;
    }

    // 默认选项
    bool ignoreCase = false;
    bool highlight = false;

    // 解析命令行参数
    string pattern;
    int opt;
    while ((opt = getopt(argc, argv, "ih")) != -1) {
        switch (opt) {
            case 'i':	// 忽略大小写
                ignoreCase = true;
                break;
            case 'h':	// 高光显示
                highlight = true;
                break;
            default: /* '?' */
                usage(EXIT_FAILURE);
                return 1;
        }
    }

    // 获取搜索模式
    if (optind < argc) {
        pattern = argv[optind];
    } else {
        cerr << "Usage: " << argv[0] << " [-i] [-h] pattern" << endl;
        return 1;
    }

    // 执行搜索
    grep(pattern, cin, ignoreCase, highlight);

    return 0;
}

void grep(const string& pattern, istream& input, bool ignoreCase, bool highlight) {
    string line;
    
    // 如果输入流不是终端，则从输入流中逐行读取内容进行搜索
    if (!isatty(STDIN_FILENO)) {
        while (getline(input, line)) {
            string searchStr = line;
            string searchPattern = pattern;

            // 如果忽略大小写，则将搜索字符串和模式转换为小写
            if (ignoreCase) {
                transform(searchStr.begin(), searchStr.end(), searchStr.begin(), ::tolower);
                transform(searchPattern.begin(), searchPattern.end(), searchPattern.begin(), ::tolower);
            }

            // 在搜索字符串中查找模式
            size_t found = searchStr.find(searchPattern);
            if (found != string::npos) {
                // 如果找到了匹配的部分
                if (highlight) {
                    // 高亮显示匹配到的部分
                    size_t startPos = line.find(searchPattern);
                    size_t endPos = startPos + searchPattern.length();
                    // 输出到标准错误流，因为标准错误流不会被重定向
                    cerr << line.substr(0, startPos) << "\033[1;31m" << line.substr(startPos, endPos - startPos) << "\033[0m" << line.substr(endPos) << endl;
                    // 如果输出流不是终端，则也输出到标准输出流
                    if (!isatty(STDOUT_FILENO)) 
                        cout << line.substr(0, startPos) << "\033[1;31m" << line.substr(startPos, endPos - startPos) << "\033[0m" << line.substr(endPos) << endl;
                } else {
                    // 如果不需要高亮显示，则直接输出行到标准错误流和标准输出流（如果输出流不是终端）
                    if (!isatty(STDOUT_FILENO)) cout << line << endl;
                    cerr << line << endl;
                }
            }
        }
    }
}

void usage(int status) {
    std::cerr << "\033[32m" << "用法: mygrep [-i] [-h] 模式" << "\033[0m" << std::endl;
    std::cerr << "搜索匹配模式的行，并将它们打印到标准输出。" << std::endl;
    std::cerr << "\033[32m" << "选项：" << "\033[0m" << std::endl;
    std::cerr << "  -i      在模式和输入文件中忽略大小写区别。" << std::endl;
    std::cerr << "  -h      在输出中突出显示匹配到的模式。" << std::endl;
    std::cerr << "  --help  显示此帮助信息并退出。" << std::endl;
    std::exit(EXIT_SUCCESS);
}